
    
  #include "experiment.h"

 
  

  /************************************************************************
          Definizione delle variabili e delle funzioni esterne
  ************************************************************************/

    
  
  extern void rmarin(int ij, int kl);
  /* E' la funzione chiamata dalla procedura randomize e serve alla 
     generazione dei numeri casuali.*/   
  
  extern class Variables built_ins;
  /* E' la classe che contiene tutte le informazioni. */ 
 
  
  /******************************************************************
          Definizione delle funzioni e delle variabili utilizzate
  ******************************************************************/
  
  // class Experiment experiment;
  /* E' l'oggetto utilizzato per eseguire l'esperimento.
  */
  
  

  /*
  ----------------- Procedura Run -----------------------------------------
  *** Scritta il: 13/1/04
  E' la procedura costruttrice della classe Run ed  e' vuota.
  *** Ultima modifica:
  */
  Run::Run()
  {
     return;
  }
  
  /*
  ----------------- Procedura Run -----------------------------------------
  *** Scritta il: 13/1/04
  E' la procedura costruttrice della classe Run ed  e' vuota.
  *** Ultima modifica:
  */
  void Run::alloc_mem(int iters_num, int vars_num)
  {
     int i;
     vars_story = new variable*[iters_num];
     
     for (i=0; i < iters_num; ++i)
        vars_story[i] = new variable[vars_num];
     
     return;
  }

  /*
  ----------------- Procedura show ----------------------------------------
  *** Scritta il: 13/1/04
  Mostra l'andamento della fitness e delle variabili built-in sull'output 
  passato come parametro, del run passato come parametro.  
  *** Ultima modifica:
  */
  void Experiment::show_run(int run, ofstream *out_stream)
  {
    int vars_num, i, j;
    string tmp_str;
    
    
    // Si calcola il numero di variabili da visualizzare.
    vars_num = built_ins.give_Num();
    
    //  **** Si visualizza la riga dei nomi abbreviati delle variabili. ***
    
    // Si visualizza prima le variabili di fitness.
    *out_stream<<endl<<"iter  b_fit a_fit";
    
    // Si visualizzano le variabili built-in.
    for (i=0; i < vars_num; ++i)
    {
       set_output(out_stream, 5, 7);       
       *out_stream<<" b_" + built_ins.give_short(i)<<" a_" + 
                    built_ins.give_short(i);
       
       /* Si controlla se devono essere visualizzati anche minimi e massimi
       per l'i-esima variabile. */
       if (built_ins.show_max_min(i))
         *out_stream<<" x_"+built_ins.give_short(i)<<
                    " n_"+built_ins.give_short(i);
    }    
    // Si va a capo.
    *out_stream<<endl; 
    
    for (i=0; i < runs[run].iters_done; ++i)
    {
       // *** Formattazione
       set_output(out_stream, 5, 7);
       //out_stream->width(5);
       //out_stream->setf(ios::left);   
       
       // Si stampa l'iterazione corrente.
       *out_stream<<endl<<i<<" ";
       
       // Si visualizza prima l'andamento della fitness.
       
       // *** Formattazione
       set_output(out_stream, 5, 7);
       //out_stream->width(5);
       //out_stream->setf(ios::left);    
       // Visualizzazione
       *out_stream<<runs[run].bestfit_story[i]<<" ";
       
       // *** Formattazione
       set_output(out_stream, 5, 7);
       //out_stream->width(5);
       //out_stream->setf(ios::left);
       // Visualizzazione
       *out_stream<<runs[run].avefit_story[i]<<" ";
       
       // Adesso si visualizzano le variabili built-in.
       for (j=0; j < vars_num; ++j)
       {
          // *** Formattazione
          set_output(out_stream, 5, 7);
          //out_stream->width(5);
          //out_stream->setf(ios::left);   
          // Visualizzazione
          *out_stream<<runs[run].vars_story[i][j].best_val<<" ";
          
          // *** Formattazione
          set_output(out_stream, 5, 7);
          //out_stream->width(5);
          //out_stream->setf(ios::left);
          // Visualgizzazione
          *out_stream<<runs[run].vars_story[i][j].ave_val<<" ";
          
          /* Si controlla se devono essere visualizzati anche minimi e mas-
             simi per l'i-esima variabile. */
                    
          if (built_ins.show_max_min(j))
          {
            // *** Formattazione
            set_output(out_stream, 5, 7);
            //out_stream->width(5);
            //out_stream->setf(ios::left);
            // Visualizzazione
            *out_stream<<runs[run].vars_story[i][j].max_val<<" ";
            // *** Formattazione
            set_output(out_stream, 5, 7);
            //out_stream->width(5);
            //out_stream->setf(ios::left);
            // Visualizzazione
            *out_stream<<runs[run].vars_story[i][j].min_val<<" ";
          }      
       }       
    }      
            
    return;
  }
  

  /*
  ----------------- Procedura show ----------------------------------------
  *** Scritta il: 13/1/04
  Visualizza sullo stream  passato come parametro l'andamento medio dei run
  *** Ultima modifica:
  */
  void Experiment::show_ave_run(ofstream *out_stream)
  {
    int vars_num, i, j, run;
    string tmp_str;
    
    
    // Si calcola il numero di variabili da visualizzare.
    vars_num = built_ins.give_Num();
    
    //  **** Si visualizza la riga dei nomi abbreviati delle variabili. ***
    
    // Si visualizza prima le variabili di fitness.
    *out_stream<<endl<<"iter  b_fit a_fit";
    
    // Si visualizzano le variabili built-in.
    for (i=0; i < vars_num; ++i)
    {
       set_output(out_stream, 5, 7);       
       *out_stream<<" b_" + built_ins.give_short(i)<<" a_" + 
                    built_ins.give_short(i);
       
       /* Si controlla se devono essere visualizzati anche minimi e massimi
       per l'i-esima variabile. */
       if (built_ins.show_max_min(i))
         *out_stream<<" x_"+built_ins.give_short(i)<<
                    " n_"+built_ins.give_short(i);
    }    
    // Si va a capo.
    *out_stream<<endl; 
    
    for (i=0; i < runs[0].iters_done; ++i)
    {
       // *** Formattazione
       set_output(out_stream, 5, 7);
       //out_stream->width(5);
       //out_stream->setf(ios::left);   
       
       // Si stampa l'iterazione corrente.
       *out_stream<<endl<<i<<" ";
       
       // Si visualizza prima l'andamento della fitness.
       
       // *** Formattazione
       set_output(out_stream, 5, 7);
       //out_stream->width(5);
       //out_stream->setf(ios::left);    
       // Visualizzazione

       // Calcolo della media
       float ave_fit = 0.0;
       for (run=0; run < N_runs; ++run)
          ave_fit += runs[run].bestfit_story[i];
       
       // Visualizzazione
       *out_stream<<ave_fit / N_runs<<" ";
       
       // *** Formattazione
       set_output(out_stream, 5, 7);
       //out_stream->width(5);
       //out_stream->setf(ios::left);
       
       
         // Calcolo della media
       float ave_ave_fit = 0.0;
       for (run=0; run < N_runs; ++run)
          ave_ave_fit += runs[run].avefit_story[i];
       
       // Visualizzazione
       *out_stream<<ave_ave_fit / N_runs<<" ";

              
       // Adesso si visualizzano le variabili built-in.
       for (j=0; j < vars_num; ++j)
       {
          //************ calcolo dei best *************************
          // *** Formattazione
          set_output(out_stream, 5, 7);
          //out_stream->width(5);
          //out_stream->setf(ios::left);   

          // Calcolo della media
          float ave_best_val = 0.0;
       for (run=0; run < N_runs; ++run)
          ave_best_val += runs[run].vars_story[i][j].best_val;

           
          // Visualizzazione
          *out_stream<<ave_best_val / N_runs<<" ";
          
          //************ calcolo delle medie **********************
          
          // *** Formattazione 
          set_output(out_stream, 5, 7);
          //out_stream->width(5);
          //out_stream->setf(ios::left);

             // Calcolo della media
          float ave_ave_val = 0.0;
       for (run=0; run < N_runs; ++run)
          ave_ave_val += runs[run].vars_story[i][j].ave_val;

          
          // Visualizzazione
          *out_stream<<ave_ave_val / N_runs<<" ";
          
         
       }       
    }      
            
    return;
  }
  
  
  /*
  ----------------- Procedura Experiment ----------------------------------
  *** Scritta il: 13/1/04
  E' la procedura costruttrice della classe Experiment ed  e' vuota.
  *** Ultima modifica:
  */
  Experiment::Experiment()
  {
     return;
  }
  
  /*
  ----------------- Procedura get_params ----------------------------------
  *** Scritta il:
  Legge da file i parametri dell'evoluzione da implementare. Alla procedura 
  viene passata la riga di comando per controllare se aprire il file di de-
  fault oppure un passato dall'utente.
  *** Ultima modifica: ore 16.00 del 04/04/03
  */
  void Experiment::get_params(int argc, char *argv[])
  {
     FILE *file_ptr; 	  
     char line[MAX_CHAR_LINE], *line_ptr;
     int i, params, N_params;
     
     
     /* Si inizializza la stringa che deve contenere il nome del file dei 
       parametri. */ 
     for (i=0; i < MAX_CHAR_FILE_NAME; ++i)
        par_file_name[i] = '\0';   


     /* Si verifica la riga di comando per comprendere se i parametri sono
        stati memorizzati in un file. */
     if (read_param(argc, argv, "-e", par_file_name))
       // Si apre il file passato dall'utente alla riga di comando.
       file_ptr = fopen(par_file_name, "r");
     /* I parametri vanno letti dalla riga di comando oppure sono quelli di
        default. */ 
     else 
     {
       /* Prima di verificare la riga di comando si settano i parametri di 
          default. */
       set_def_params();
       
       /* Si chiama la procedura specifica della classe per l'acquisizione 
          da riga di comando dei parametri relativi alla sperimentazione.*/
       read_line_params(argc, argv); 
       
       /* Adesso si esce dalla procedura, in quanto l'eventuale caricamento
          dei parametri di default e' stato gia' effettuato. */
       return;    
     }   
       
           
     // Si controlla se il file e' stato aperto correttamente.
     if (file_ptr == NULL)
       abort_message("Impossibile aprire il file \"%s\" \n \
       per la lettura dei parametri per la sperimentazione!", par_file_name);     
     
     
     // Prima si acquisisce il numero di parametri presenti nel file.
     get_line(line, file_ptr, MAX_CHAR_LINE);

     if (!get_int(line, "N_PARAMS", N_params))
       /* Se non si riesce ad acquisire il numero di paarmetri, il program-
          ma viene terminato. */
       abort_message("ERRORE ! Impossibile trovare \"N_PARAMS\" nel\
        file %s", par_file_name);


     /* Il ciclo che segue legge da file tutti i parametri dell'evo-
        luzione. */
     params = 0;

     while ((get_line(line, file_ptr, MAX_CHAR_LINE)) && 
            (params < N_params))
     {
        if (extract_param(line))
          ++params;
        else abort_message("ERRORE durante la lettura del file %s",
                            par_file_name);
     }
     if (params < N_params)
       abort_message("Il numero di parametri contenuto nel file %s e' \
       insufficiente", par_file_name);
     fclose(file_ptr);      

     return;
  }
  
  /*
  ----------------- Procedura check_params --------------------------------
  *** Scritta il: 13/1/04
  Verifica se i valori dei parametri dell'esperimento sono validi. 
  *** Ultima modifica: ore 16.00 del 04/04/03
  */
  void Experiment::check_params()
  {
     /* Si verifica se il numero di runs da effettuare e' maggiore di quel-
        lo consentito. */
     if (N_runs > MAX_RUNS)
       abort_message("Il parametro n_runs e' maggiore del numero \
       massimo consentito (%d), correggere il valore della costante \
       MAX_RUNS nel file experiment.h", MAX_RUNS);

     /* Si verifica se il numero massimo di individui e' maggiore del mas-
        simo consentito. */
     

     return;
  }

  
  /*
  ----------------- Procedura extract_param -----------------------------
  *** Scritta il:
  Estrae dalla linea in input il parametro contenuto e lo assegna al re-
  lativo attributo.
  *** Ultima modifica: ore 16.00 del 04/04/03
  */
  bool Experiment::extract_param(char *line)
  {
     char *line_ptr;     

     /* Si convertono i minuscolo tutti i caratteri presenti nella linea
        passata come parametro. */
     str_lwr(line, MAX_CHAR_LINE);
     

     // ***************** Numero di run ***********************************
     if (strstr(line, "n_runs"))
       if (get_int(line, "n_runs", N_runs))
          return true;
       else abort_message("ERRORE ! Nella lettura del parametro \
		       \"N_runs\"!");
		       
	// ***************** seed 1 *******************************************
     if (strstr(line, "seed1"))
       if (get_int(line, "seed1", seed1))
          return true;
       else abort_message("ERRORE ! Nella lettura del parametro \
		       \"seed1\"!");	 
         
     // ***************** seed 2 ******************************************
     if (strstr(line, "seed2"))
       if (get_int(line, "seed2", seed2))
          return true;
       else abort_message("ERRORE ! Nella lettura del parametro \
		       \"seed2\"!");
		       
     // ***************** file dei risultati ******************************
     if (strstr(line, "file"))
       if (get_string(line, "file", line_ptr))
       {
         /* Il nome del file dove memorizzare i risultati viene copiato nel
            relativo attributo. */
         strcpy(res_file_name, line_ptr);
              
         return true;
       }       
       else abort_message("ERRORE ! Nella lettura del parametro \
		       \"file\"!");	                          	                 
          
     // La riga NON e' valida!
     abort_message("ERRORE ! Nella lettura dei parametri! \
		           Questa linea e' sbagliata: %s\n", line);
  }
  
  /*
  ----------------- Procedura set_def_params ------------------------------
  *** Scritta il:
  Setta gli attributi della classe ai valori di default.
  *** Ultima modifica: ore 16.00 del 04/04/03
  */
  void Experiment::set_def_params()
  {
      
     // Assegnazione dei seed.
     seed1 = DEF_SEED1; 
     seed2 = DEF_SEED2;        
     
     // Assegnazione del numero di run.
     N_runs = DEF_RUNS;
     
     // Assegnazione del nome del file di default.
     strcpy(res_file_name, DEFAULT_RES_FILE);
     
     return;  
  }
  
  /*
  ----------------- Procedura read_line_params ----------------------------
  *** Scritta il:
  Legge dalla riga di comando gli eventuali parametri passati dall'utente.
  *** Ultima modifica: ore 16.00 del 04/04/03
  */
  void Experiment::read_line_params(int argc, char *argv[])
  {
     int seed;
     char tmp_string[256];
     
     
     //************** Caricamento dei seed ********************************
     
     /* Si controlla se e' stato passato il primo seed. In tal caso esso 
        viene memorizzato come stringa.  */
     if (read_param(argc, argv, "-s1", tmp_string))
       /* La stringa viene convertita in numero e memorizzata nel relativo
          attributo. */ 
       seed1 = atoi(tmp_string);
       
    // Si ripete la cosa per il secondo seed.
    if (read_param(argc, argv, "-s2", tmp_string))
       seed2 = atoi(tmp_string);
     
     // Si passa un seed, senza specificare quale.
    if (read_param(argc, argv, "-s", tmp_string))
      if (flip(0.5))  
        seed1 = atoi(tmp_string);
      else seed2 = atoi(tmp_string);
       
    //************** Caricamento del numero di run ************************ 
    if (read_param(argc, argv, "-n", tmp_string))
      N_runs = atoi(tmp_string);
      
   //************** Caricamento del nome del file *************************
   if (read_param(argc, argv, "-r", tmp_string))
      strcpy(res_file_name, tmp_string);
        
  }
  
  /*
  ----------------- Procedura alloc_runs_mem ------------------------------
  *** Scritta il: 13/1/04
  E' la procedura che alloca la memoria per l'array di oggetti della classe
  Run da utilizzare per la memorizzazione dei dati dei singoli run. Il pri-
  mo parametro indica il numero di iterazioni dell'alogoritmo, mentre il 
  secondo specifica il numero di variabili da memorizzare.
  *** Ultima modifica:
  */
  void Experiment::alloc_runs_mem(int iters_num, int vars_num)
  {
    int i;   
    /* Per l'allocazione di memoria per l'array di oggetti della classe Run
       basta una singola chiamata... */
    runs = new Run[N_runs]; //(iters_num, vars_num);
    
    for (i=0; i < N_runs; ++i)
       runs[i].alloc_mem(iters_num, vars_num);
    
    return;
      
  }
        
   /*
  ----------------- Procedura execute -------------------------------------
  *** Scritta il: 13/1/04
  E' la procedura che esegue l'esperimento, eseguendo il numero di runs 
  previsto.
  *** Ultima modifica:
  */
  void Experiment::execute(int args_num, char *args[], Evolution *evo_pointer) 
  {
    int i, best_run;
    ofstream out_stream;
     
    /* Si memorizza il puntatore all'oggetto della classe Evolution pas-
       sato come parametro. */
    evo_ptr = evo_pointer;
    
    // Si controlla il puntatore.
    if (evo_ptr == NULL)
      abort_message("ERRORE: \n procedura: Experiment::execute, il puntatore \
      alla classe Evolution e' nullo!");
      
    // Si caricano iparametri relativi alla sperimentazione da effettuare.
    get_params(args_num, args);       
    
    // Si controlla se i parametri sono validi.
    check_params();
      
    // Si acquisiscono i nomi delle variabili built ins utilizzate.
    built_ins.get_names(true);  
    
            
    /* Si apre il file che deve essere utilizzato per la memorizzazione dei
       risultati. */
    out_stream.open(res_file_name, ios::app);   
    
    // Si controlla la corretta apertura del file.
     if (!out_stream)
       abort_message("\nATTENZIONE\nImpossibile aprire il file: %s",
                     res_file_name);
     // Memorizzazione dell'ora inizio dell'esecuzione.
     else
       {	     
         out_stream<<"\n\n                       *****************\n";
         out_stream<<" \n Inizio dell'esecuzione: "<< get_time();         
         out_stream.flush();
       }
    
    /* Si chiama la procedura di inizializzazione del generatore di numeri
       casuali. */
    ini_seeds();
    
    // Si Chiama la procedura start della classe Evolution.
    evo_ptr->start(args_num, args);
    
    /* Si chiama la procedura che alloca memoria per la memorizzazione dei
       dati dei singoli runs. */
    alloc_runs_mem(evo_ptr->give_iters_num(), built_ins.give_Num());
         
    // Esecuzione dell'algoritmo per un numero fissato di volte.    
    for (i=0; i < N_runs; ++i)
    {       
       cout<<endl<<get_time()<<" run numero "<<i+1<<":"; 
       
       // Serve a inizializzare stutture che vanno inizializzate prima di ogni run 
       evo_ptr->init_run(args_num, args);
       
       // Esecuzione dell'algoritmo.
       evo_ptr->find_super(false);
    
       // Memorizzazione della migliore soluzione ottenuta.
       memo_run(i);
       out_stream<<endl<<i+1<<" fit:"<<runs[i].give_best_fit()<<" i:"<<runs[i].give_best_iter()<<flush;
       
	
       /* Vengono liberate le risorse utilizzate, in maniera tale da ren-
	      dere possibile l'esecuzione di un altro run. */        
       free_memory(evo_ptr);
       
	   
       // Si genera una nuova popolazione iniziale.       
       evo_ptr->curr_pop->breed(); 
       
       
       
       // Si forza la scrittura in output del messaggio.
       cout.flush();
    }

    // Calcoli statistici e memorizzazione dei risultati.
    best_run = find_best_run(evo_ptr->problem_type);   
    comp_means();
    comp_deviations(); 
    memo_data(best_run, &out_stream);  
    
     

    cout<<endl<<"I risultati sono stati memorizzati nel file: "<<
                res_file_name<<endl;


    return;
  }  


   /* ----------------- Procedura memo_run ---------------------------------
     *** Scritta il:
     Memorizza nell'elemento i-esimo passato come parametro i dati ottenuti
     dal run attuale dell'algoritmo.
     *** Ultima modifica: ore 16.00 del 04/04/03
   */ 
   void Experiment::memo_run(int run)
   {
     int i, j;
     double tmp_sum;
     
      
     /* Si memorizza l'iterazione in cui e' stata ottenuta la migliore so-
        luzione. */
     runs[run].best_iter = evo_ptr->best_iter;     
       
     // Si memorizza il migliore individuo del run. 
     runs[run].best_ind = evo_ptr->best_so_far;
       
     // Si memorizza il numero di iterazioni realmente effettuate.
     runs[run].iters_done = evo_ptr->iters_done;
      
     /******************       IMPORTANTE!            *****************
      ATTENZIONE!: Questa copia del migliore individuo ottenuto durante il
      run NON contiene l'albero di derivazione. In quanto l'attributo root
      della copia punta allo stesso albero dell'originale che nel frattempo 
      e' stato DISTRUTTO! 
     */
  
     // Si memorizzano i valori di fitness migliore ottenuti durante il run.
     for (i=0; i < evo_ptr->give_iters_done(); ++i)
        runs[run].bestfit_story[i] = evo_ptr->bestfit_story[i];
  
    /* Si memorizzano i valori medi della fitness della popolazione durante
       il run.  */
     for (i=0; i < evo_ptr->give_iters_done(); ++i)
        runs[run].avefit_story[i] = evo_ptr->avefit_story[i];
          
        
     // Si memorizzano i valori delle variabili built-in.
     for(i=0; i < evo_ptr->give_iters_done(); ++i) 
        for (j=0; j < built_ins.give_Num(); ++j)        
           runs[run].vars_story[i][j] = evo_ptr->vars_story[i][j];   
 
                  
     return;
   }


   /* ----------------- Procedura find_best_run ----------------------------
     *** Scritta il:
     Trova il miglior run assoluto fra tutti quelli effettuati durante la
     prova. E ritorna come valore la sua posizione all'interno del vettore
     runs.
     *** Ultima modifica: ore 16.00 del 04/04/03
  */
   

   int Experiment::find_best_run(problem_types type)
   {
       int i, best_run;
       double best_fit;

       // Fase di inizializzazione.
       best_run = 0;
       best_fit = runs[0].best_ind->give_fitness();

        
       /* Ricerca del run migliore (quello che ha ottenuto la soluzione mi-
          gliore) nel vettore runs. */
       for (i=1; i < N_runs; ++i)
          /* Si controlla se e' un problema di minimizzazione o di massi-
            mizzazione. */
          if (type == max_)
          {  
            // E' un problema di MASSIMIZZAZIONE.
            if (runs[i].best_ind->give_fitness() > best_fit)
            { 
              best_run = i;
              best_fit = runs[i].best_ind->give_fitness();
              
            }
	        else if (runs[i].best_ind->give_fitness() == best_fit)
                 /* A parita' di fitness si giudica migliore il run che ot-
                    tenuto prima la soluzione. */
	               if (runs[i].best_iter < runs[best_run].best_iter)
                      best_run = i;
          }
          // E' un problema di MINIMIZZAZIONE.
          else
          {
            if (runs[i].best_ind->give_fitness() < best_fit)
               {
                 best_run = i;
                 best_fit = runs[i].best_ind->give_fitness();
               }
	           else if (runs[i].best_ind->give_fitness() == best_fit)
	               if (runs[i].best_iter < runs[best_run].best_iter)
                      best_run = i;
          }

     // Si ritorna la posizione nel vettore run del migliore run trovato
     return best_run;
  }



  /* ----------------- Procedura comp_means -------------------------
     *** Scritta il:
     Calcola il costo medio delle migliori soluzioni trovate ad ogni
     run e il valore medio delle iterazioni impiegate per trovare la
     migliore soluzione ad ogni run.
     *** Ultima modifica: ore 16.00 del 04/04/03
   */

  void Experiment::comp_means()
  {
     int int_sum, i, clusters_sum, j;
     double tmp_sum;
	 

     // Calcolo del valor medio della FITNESS delle migliori soluzioni.
     tmp_sum = 0.0;

     for (i = 0; i < N_runs; ++i)
        tmp_sum += runs[i].best_ind->give_fitness();

     ave_fit = tmp_sum / N_runs;
       
        
     /* Calcolo del valor medio delle ITERAZIONI delle migliori soluzi-
        oni. */
     int_sum = 0;

     for (i = 0; i < N_runs; ++i)
        int_sum += runs[i].best_iter;       
           
     ave_iter = (double) int_sum / (double) N_runs;    
        
     // Calcolo del valor medio delle variabili BUILT-IN     
     for (i=0; i < built_ins.give_Num(); ++i)
     {
        tmp_sum = 0.0;

        for (j = 0; j < N_runs; ++j)
           tmp_sum += runs[j].best_ind->give_var(i);

        vars[i].ave_val = tmp_sum / N_runs;
     }       
            
     
	 return;
   }


  /* ----------------- Procedura comp_deviations -------------------
     *** Scritta il:
     Calcola le deviazioni standard delle migliori soluzioni e delle
     iterazioni delle migliori soluzioni. 
     *** Ultima modifica: ore 16.00 del 04/04/03
  */

   void Experiment::comp_deviations()
   {
     double tmp_sum;
     int i, j;

	    // Calcolo della deviazione standard della FITNESS.
        tmp_sum = 0.0;

        for (i = 0; i < N_runs; ++i)
           tmp_sum += pow((double) runs[i].best_ind->give_fitness() - ave_fit,
                           2.0);

        dev_fit = sqrt(tmp_sum / (double) (N_runs));

 
	    // Calcolo della deviazione standard delle iterazioni.
        tmp_sum = 0.0;

        for (i = 0; i < N_runs; ++i)
           tmp_sum += pow((double) runs[i].best_iter - ave_iter, 2.0);

        dev_iter = sqrt(tmp_sum / (double) (N_runs ));
        
        
        // Calcolo della deviazione standard delle variabili built-in.
        
        for (i=0; i < built_ins.give_Num(); ++i)
        {
           tmp_sum = 0.0;

           for (j = 0; j < N_runs; ++j)
              tmp_sum += pow((double) runs[j].best_ind->give_var(i) - 
                         vars[i].ave_val, 2.0);

           vars[i].dev_val = sqrt(tmp_sum / (double) (N_runs ));
        }       
        
 	
	return;
   }
                               


  /* ----------------- Procedura memo_data --------------------------------
     *** Scritta il:
     Stampa  in un file tutti i  parametri utilizzati,  la  migliore  solu-
     zione  trovata  durante  le  prove effettuate e i dati statistici. Il
     parametro best specifica qual'e' il miglior run dell'esperimento.      
     *** Ultima modifica: ore 16.00 del 04/04/03
  */
  void Experiment::memo_data(int best, ofstream *out_stream)
  {
     ifstream *tmp_stream;
     char file_name[MAX_CHAR_FILE_NAME];
     int i, j;
     double tmp_sum;
     Individual *ind_ptr;
     
     // Visualizzazione di un messaggio di avviso.
     cout<<endl<<"memorizzazione dei risultati..."<<endl;

     // Si fissa la larghezza dei numeri in uscita.
     //out_stream->width(5);
     //out_stream->precision(3);
     //out_stream->setf(ios::left);
     set_output(out_stream,5,3);
     

     /* Si il tempo di inizio e i semi per il generatore di numeri
        casuali*/
     *out_stream<<"\n numero di prove effettuate: "<<N_runs;
     *out_stream<<" \n valore dei semi del generatore dei numeri";
     *out_stream<<" casuali: "<<" "<<seed1<<" "<<seed2;
     *out_stream<<" \n Termine dell'esecuzione: "<<get_time();

           
     // Si memorizzano i parametri dell'evoluzione utilizzati.
     *out_stream<<"\n       $$$$  PARAMETRI EVOLUTIVI njjn$$$$\n";
     
     // Si chiama la procedura specifica della Evolution.
     evo_ptr->give_params(out_stream);
     
     // Si chiama una procedura (virtuale) per salvare eventuali altri parametri
     evo_ptr->give_more_params(out_stream);

     
     // Si controlla se e' presente un oggetto fitmess.
     if (evo_ptr->fitness != NULL)
     {
       // Si memorizzano i parametri di fitness utilizzati.
       *out_stream<<"\n       $$$$  FITNESS  $$$$\n";
      
       /* Si chiama la procedura specifica per la copia del file che conti-
          ene i parametri della fitness. */
       evo_ptr->fitness->give_params(out_stream);
     }    
      

     // *************** MEMORIZZAZIONE DEI RISULTATI OTTENUTI ************
     *out_stream<<"\n       $$$$  RISULTATI $$$$ \n";
     
     //Si chama la procedura per la visualizzazione delle variabili.
     
     // FITNESS
     show_var(ave_fit, dev_fit, "fitness", out_stream);     
     
     // ITERAZIONI
     show_var(ave_iter, dev_iter, "iters", out_stream);
     
     // Si visualizzano le variabili BUILT-IN.
     for (i=0; i < built_ins.give_Num(); ++i)
        show_var(vars[i].ave_val, vars[i].dev_val, built_ins.give_full(i),
                 out_stream);
     
      
     // BEST
     *out_stream<<"\n\n  ********** Individuo migliore:";
     *out_stream<<"\n Trovato durante il run numero: "<<best + 1;
     *out_stream<<"\n Iterazione: "<<runs[best].best_iter;
     
     /* Si inseriscono i  dati nel file chiamando la procedura di visualiz-
        zazione specifica dell'individuo.  */
    runs[best].best_ind->show(out_stream);  
       
                       
     // Si stampano anche gli altri migliori individui trovati nel run.
     *out_stream<<"\n\n ***** Lista degli ALTRI MIGLIORI individui **** \n";
     
     for (i=0; i < N_runs; ++i)
        if (i != best)
        { 
          *out_stream<<"\n\n******** RUN numero: "<<i + 1<< "*****";
          *out_stream<<"\n Iterazione: "<<runs[i].best_iter;         
          runs[i].best_ind->show(out_stream);
      
        }
        
     // Si visualizza la LEGENDA.
     built_ins.show_legend(out_stream); 
 
     // Si memorizza l'andamento del run migliore.
     for (i=0; i < N_runs; ++i )
        if (i == best)
     {    
          *out_stream<<"\n\n  ******* ANDAMENTO DEL RUN NUMERO: "<<i + 1<<
                     " *****";
          show_run(i, out_stream);
     }    
           
     // Si memorizza l'andamento medio dei run.
     *out_stream<<"\n\n  ******* ANDAMENTO MEDIO  DEI RUN *****";
          show_ave_run(out_stream);
     return;
   }


  /* ----------------- Procedura ini_seeds --------------------------------
     *** Scritta il:
     E' la versione di randomize da usare per l'esecuzione di piu' run.
     *** Ultima modifica: ore 16.00 del 04/04/03
  */
  void Experiment::ini_seeds( )
  {  
        
    /* Si chiama la procedura di inizializzazione dei seeds utilizzando gli
       attributi precedentemente caricati da file, da linea di comando o di
       default. */
    rmarin(seed1, seed2);
    
    
    return;

  }
  
  /*
  ----------------- procedura free_memeory --------------------------------
  Scritta il: 16/1/04
  Questa procedura libera le risorse di memoria allocate dall'oggetto della
  classe Evolution passato come parametro.
  passata come parametro.
  *** Ultima modifica: ore 16.00 del 04/04/03
  */
  void Experiment::free_memory(Evolution *evo_ptr)
  {
     // Si liberano le risorse allocate dalla popolazione corrente.
     evo_ptr->curr_pop->kill();
     evo_ptr->next_pop->kill();
          
               
     return;
  }
  
  
  /*
  ----------------- procedura show_var ------------------------------------
  Scritta il: 16/1/04
  Questa procedura visualizza i dati relativi ad una varuabile.
  Il primo parametro specifica il valore medio, il secondo la deviazione,
  il terzo il suo nome, il quarto l'output. 
  *** Ultima modifica: ore 16.00 del 04/04/03
  */
  void Experiment::show_var(double ave, double dev , string name,  
                            ofstream *out_stream)
  {
     *out_stream<<endl<<endl<<"  ==== Variabile: "<<name<<" ==== "; 
     *out_stream<<endl<<" valore medio: "<<ave;  
     *out_stream<<" deviazione: "<<dev;
     
          

     return;
  }	
  
  
